import axios from 'axios'
import { ElMessage, ElLoading } from 'element-plus'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from '@/utils/index'
import { saveAs } from 'file-saver'
import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper'

let downloadLoadingInstance;
// 是否显示重新登录
export let isRelogin = { show: false };

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项，表示请求URL公共部分
  // baseURL: import.meta.env.VITE_APP_BASE_API,
  // 超时
  timeout: 10000
})

// request拦截器
service.interceptors.request.use(
  config => {
    // do something before request is sent

    if (getToken()) {
      // 默认携带token
      config.headers['X-Okapi-Token'] = getToken()
    }
    config.headers['Accept'] = '*/*'
    config.headers['X-Okapi-Tenant'] = localStorage.getItem('x-Okapi-Tenant') || 'a000001' // 租客ID
    config.url = import.meta.env.VITE_APP_BASE_API + config.url // 动态url

    return config
  },
  error => {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  }
)

// folio登录返回报错英转汉
const folioErrorTranslate = [
  { msg: 'Password does not match', chinese: '登录名或密码错误' }, // 密码不匹配
  { msg: 'User must be flagged as active', chinese: '用户未激活' },
  { msg: 'Error verifying user existence: No user found by username', chinese: '此用户不存在' },
  { msg: 'You must provide a username or userId', chinese: '用户名不能为空' },
  { msg: 'No credentials match that login', chinese: '没有凭据与该登录名匹配' },
  { msg: 'Error verifying user existence', chinese: '登录名或密码错误' }, // Error verifying user existence, 验证用户存在错误
  { msg: 'User could not be verified as active', chinese: '用户无法被核实为活跃用户' },
  { msg: 'Error retrieving stored hash and salt from credentials', chinese: '凭证验证错误' }
]

// 响应拦截器
service.interceptors.response.use(res => {
    // Folio 接口特殊处理
    if (res.statusCode === 400) {
      let msg = ''
      folioErrorTranslate.forEach((trans) => {
        if (res.errorMessage.indexOf(trans.msg) !== -1) {
          msg = `${trans.chinese} `
        }
      })
      ElMessage({
        message: msg || res?.errorMessage,
        type: 'error',
        duration: 5 * 1000
      })
      return {
        data: null,
        code: '',
        msg: msg || res?.errorMessage,
        message: msg || res?.errorMessage
      }
    }

    if (res && res.errors && res.errors.length > 0) {
      let msg = ''
      res.errors.forEach((error) => {
        folioErrorTranslate.forEach((trans) => {
          if (trans.msg === error.message || error.message.indexOf(trans.msg) !== -1) {
            msg += `${trans.chinese} `
          }
        })
      })
      ElMessage({
        message: msg,
        type: 'error',
        duration: 5 * 1000
      })
      return { data: null, code: '', msg: res.errors, message: res.errors }
    }

    if (res && res.errorMessage) {
      let msg = ''
      folioErrorTranslate.forEach((trans) => {
        if (res.errorMessage.indexOf(trans.msg) !== -1) {
          msg = `${trans.chinese} `
        }
      })
      ElMessage({
        message: msg,
        type: 'error',
        duration: 5 * 1000
      })
      return { data: null, code: '', msg: res.errorMessage, message: res.errorMessage }
    }

    // 过滤掉 Folio 接口的返回 422 或者 500
    if (res.statusCode === 422 || res.statusCode === 500) {
      ElMessage({
        message: `服务器错误 ${res.statusCode}`,
        type: 'error',
        duration: 5 * 1000
      })
      return { data: null, code: '', msg: '服务端错误', message: '服务端错误' }
    }

    return res
  },
  error => {
    if (error) {
      const { response } = error
      const message = (msg) => ElMessage({
        message: msg,
        type: 'error',
        duration: 5 * 1000
      })
      let flag = false
      if (response.status === 401 && !flag) {
        if (window.location.pathname !== '/user/login' && !flag) {
          if (qiankunWindow.__POWERED_BY_QIANKUN__) {
            flag = true
            const str = window.location.href
            const arr = str.split('#')?.[0]?.split('/')
            const indexHome = arr.indexOf('home')
            const path = arr.splice(indexHome, 2).join('/')
            message('登录失效，请重新登录')
            window.location.href = `/${path}/#/user/login`
          } else {
            message('请求失效 401')
          }
          return response
        }
      } else if (response.status === 403) {
        message('请求错误 403')
        return { data: null, code: '', msg: '请求 403 错误', message: '请求 403 错误' }
      } else if (response.status === 404) {
        message('请求地址不存在')
        return { data: null, code: '', msg: '请求地址不存在', message: '请求地址不存在' }
      } else if (response.status === 504) {
        message('网关超时 504')
        return { data: null, code: '', msg: '网关超时', message: '网关超时' }
      }
      if (!response || response.status === 502) {
        message('服务端错误')
        return { data: {}, code: '', msg: '服务端错误', message: '服务端错误' }
      }
    }
    return Promise.reject(error)
  }
)

// 通用下载方法
export function download(url, params, filename, config) {
  downloadLoadingInstance = ElLoading.service({ text: "正在下载数据，请稍候", background: "rgba(0, 0, 0, 0.7)", })
  return service.post(url, params, {
    transformRequest: [(params) => { return tansParams(params) }],
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    responseType: 'blob',
    ...config
  }).then(async (data) => {
    const isBlob = blobValidate(data);
    if (isBlob) {
      const blob = new Blob([data])
      saveAs(blob, filename)
    } else {
      const resText = await data.text();
      const rspObj = JSON.parse(resText);
      const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
      ElMessage.error(errMsg);
    }
    downloadLoadingInstance.close();
  }).catch((r) => {
    console.error(r)
    ElMessage.error('下载文件出现错误，请联系管理员！')
    downloadLoadingInstance.close();
  })
}

export default service
